#include <cstdio>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>

#include "adaptive.h"

size_t n;
std::vector<point> points;
point temp;

void make(std::vector<point>& cur, size_t & si, size_t it, bool inv)
{
    if ((inv ^ (turn(points[0], points[n - 1], points[it]) >= 0)) || (it == n - 1)) 
    {
         cur.push_back(points[it]);
         ++si;
         int t;
         if (si > 2) t = turn(cur[si - 2], cur[si - 1], cur[si - 3]);
         while ((si > 2) && ((inv ^ (t > 0)) || (t == 0))) 
         {
            --si;
            temp = cur[si];
            cur.pop_back();
            cur.pop_back();
            cur.push_back(temp);
            if (si > 2) t = turn(cur[si - 2], cur[si - 1], cur[si - 3]);
         }
    };
}


int main() 
{
	std::cin >> n;
    points = std::vector<point>(n);
	for (size_t i = 0; i < n; ++i) 
		std::cin >> points[i].x >> points[i].y;
    std::cout.precision(20);
    if (n < 2)
    {
        std::cout << n << "\n";
        for (size_t i = 0; i < n; i++)
            std::cout << points[i].x << " " << points[i].y << "\n";
    }
    std::sort(points.begin(), points.end());
    std::vector<point> high, low;
    high.push_back(points[0]);
    low.push_back(points[0]);
    size_t hi = 1, lo = 1;
    for (size_t i = 1; i < n; ++i)
    {
        make(high, hi, i, false);
        make(low, lo, i, true);
    }
    if ((low[lo - 1].x == low[0].x) && (low[lo - 1].y == low[0].y))
    { 
        low.pop_back();
        lo--;
    }
    std::cout << high.size() + low.size() - 2 <<"\n";
    for (size_t i = 0; i < lo; ++i) 
        std::cout << low[i].x << " " << low[i].y << "\n";
    hi = (hi < 2) ? 0 : (hi - 2);
    for (size_t i = hi; i > 0; --i)
        std::cout << high[i].x << " " << high[i].y << "\n";
    return 0;
}